/**
 * CommunicationUtils.java
 */
package com.pluginsacceptor.utils;

import java.awt.Color;
import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import com.pluginsacceptor.api.Message;

/**
 * The class contains method for transformation information for communication between plugin
 */
public class CommunicationUtils {

    /** Init color maps to get all colors */
    private static Map<Color, String> COLOR_NAME_MAP = new HashMap<Color, String>();
    static {
        for (final Field f : Color.class.getFields()) {
            if (f.getType() == Color.class) {
                Color c;
                try {
                    c = (Color) f.get(null);
                    COLOR_NAME_MAP.put(c, f.getName());
                } catch (final Exception e) {
                    e.printStackTrace();
                }

            }
        }
    }

    /**
     * Transform information about cell to string
     * @param row the cell row number in spread sheet
     * @param col the cell column number in spread sheet
     * @param value the cell value in spread sheet
     * @return information about cell as string
     *
     *
     */
    public static String cellDataToString(final int row, final int col, final String value) {
        return MessageFormat.format(
            Message.CELL_DATA_FORMAT,
            String.valueOf(row),
            String.valueOf(col),
            value
        );
    }

    /**
     * Transform information about cell to string
     * @param row the cell row number in spread sheet
     * @param col the cell column number in spread sheet
     * @param color the cell color in spread sheet
     * @param fontType the Bold, Italic, etx
     * @return information about cell as string
     */
    public static String cellDisplayToString(
        final int row,
        final int col,
        final String color,
        final String fontType
    ) {
        return MessageFormat.format(
            Message.CELL_DISPLAY_FORMAT,
            String.valueOf(row),
            String.valueOf(col),
            color,
            fontType
        );
    }

    /**
     * Return <code>true</code> if start cell selection
     * @param message the cell message
     * @return <code>true</code>  if start cell selection
     */
    public static boolean isStartCellSelection(final String message) {
        return Message.START_SELECTION.equals(message);
    }

    /**
     * Return <code>true</code> if end cell selection
     * @param message the cell message
     * @return <code>true</code>  if end cell selection
     */
    public static boolean isEndCellSelection(final String message) {
        return Message.END_SELECTION.equals(message);
    }

    /**
     * Return <code>true</code> if empty cell
     * @param value the cell value
     * @return <code>true</code>  if empty cell
     */
    public static boolean isEmptyCell(final String value) {
        return Message.EMPTY_VALUE.equals(value);
    }

    /**
     * Return <code>true</code> if cell massage contains only value
     * @param message the cell message
     * @return <code>true</code> if cell massage contains only value
     */
    public static boolean isCellData(final String message) {
        return message.indexOf(Message.VALUE) != -1;
    }


    /**
     * Parse cell string and get row number from cell string
     * @param cellString the cell information as string
     * @return row number from cell string
     */
    public static int getRowNumFromCellString(final String cellString) {
        final String pattern = Message.ROW;
        final int ind = cellString.indexOf(pattern) + pattern.length();
        return Integer.parseInt(cellString.substring(ind, cellString.indexOf(",", ind)));
    }

    /**
     * Parse cell string and get column letter from cell string
     * @param cellString the cell information as string
     * @return column letter from cell string
     */
    public static int getColNumFromCellString(final String cellString) {
        final String pattern = Message.COL;
        final int ind = cellString.indexOf(pattern) + pattern.length();
//        return cellString.substring(ind, cellString.indexOf(",", ind));
        return Integer.parseInt(cellString.substring(ind, cellString.indexOf(",", ind)));
    }

    /**
     * Parse cell string and get value from cell string
     * @param cellString the cell information as string
     * @return value from cell string
     */
    public static String getValueFromCellString(final String cellString) {
        final String pattern = Message.VALUE;
        final int ind = cellString.indexOf(pattern) + pattern.length();
        return cellString.substring(ind, cellString.indexOf("]", ind));
    }

    /**
     * Parse cell string and get value from cell string
     * @param cellString the cell information as string
     * @return color from cell string
     */
    public static Color getColorFromCellString(final String cellString) {
        final String pattern = Message.COLOR;
        final int ind = cellString.indexOf(pattern) + pattern.length();
        final String colorName = cellString.substring(ind, cellString.indexOf(",", ind));
        Color color;
        try {
            // Using reflection for get color for name
            final Field field = Class.forName("java.awt.Color").getField(colorName);
            color = (Color) field.get(null);
        } catch (final Exception e) {
            color = null; // Not defined
        }

        return color;
    }

    /**
     * Return color as string
     * @param color the desired color
     * @return color as string
     */
    public static String colorAsString(final Color color) {
        return COLOR_NAME_MAP.get(color);
    }


    /**
     * Parse cell string and get value from cell string
     * @param cellString the cell information as string
     * @return value from cell string
     */
    public static String getFontFromCellString(final String cellString) {
        final String pattern = Message.FONT_TYPE;
        final int ind = cellString.indexOf(pattern) + pattern.length();
        return cellString.substring(ind, cellString.indexOf("]", ind));
    }

   /**
    * Returns the name of the specified column.  This method generates default
    * names in a sequence (starting with column 0):  A, B, C, ..., Z, AA, AB,
    * AC, ..., AZ, BA, BB, BC, and so on.  Subclasses may override this method
    * to allow column names to be specified on some other basis.
    *
    * @param columnIndex  the column index.
    *
    * @return The name of the column.
    */
   public static String getColumnName(int columnIndex)  {
     final StringBuffer buffer = new StringBuffer();
     while (columnIndex >= 0)
       {
         buffer.insert(0, (char) ('A' + columnIndex % 26));
         columnIndex = columnIndex / 26 - 1;
       }
     return buffer.toString();
   }

    /**
    * Return the index of the specified column, or <code>-1</code> if there is
    * no column with the specified name.
    *
    * @param columnName  the name of the column (<code>null</code> not permitted).
    *
    * @return The index of the column, -1 if not found.
    *
    * @see #getColumnName(int)
    * @throws NullPointerException if <code>columnName</code> is
    *         <code>null</code>.
    */
    public static int findColumn(final String columnName)  {

     for (int index = 0; index < 1000; index++)  {
         final String name = getColumnName(index);

         if (columnName.equals(name)) {
            return index;
        }
     }
     return -1;
    }
}
